import time
from lxml import etree

from view.ths_view.transaction_view import TransactionView
from appium.webdriver.common.appiumby import AppiumBy
from common import logger

"""
ths模拟cg页
疑难杂症定位元素的方法参考
https://blog.csdn.net/lovedingd/article/details/111058898
"""


class SimulatedView(TransactionView):
    all_elm = (AppiumBy.XPATH, "//*")
    # 个股内返回按钮
    backButton = (AppiumBy.ID, "com.hexin.plat.android:id/backButton")
    # 返回按钮
    back_btn = (AppiumBy.ID, "com.hexin.plat.android:id/title_bar_img")
    # 刷新按钮
    refresh_btn = (AppiumBy.ID, "com.hexin.plat.android:id/refresh_img")
    # 买入
    buy_btn = (AppiumBy.XPATH, "//android.widget.TextView[@text='买入']")
    # 卖出
    sale_btn = (AppiumBy.XPATH, "//android.widget.TextView[@text='卖出']")
    # 撤单
    withdrawal_btn = (AppiumBy.XPATH, "//android.widget.TextView[@text='撤单']")
    # 持仓
    holdings_btn = (AppiumBy.XPATH, "//android.widget.TextView[@text='持仓']")
    # 查询
    search_btn = (AppiumBy.XPATH, "//android.widget.TextView[@text='查询']")

    # 买入、卖出tab下的元素
    # 代码
    auto_stockcode = (AppiumBy.ID, "com.hexin.plat.android:id/auto_stockcode")
    # 输入code
    content_stock = (
        AppiumBy.XPATH,
        "//android.widget.LinearLayout[@resource-id='com.hexin.plat.android:id/content_stock']/android.widget.EditText[1]")
    # 清空输入按钮
    clear_button = (AppiumBy.ID, "com.hexin.plat.android:id/clearable_edittext_btn_clear")
    # 第一个票
    recyclerView = (AppiumBy.XPATH,
                    "//androidx.recyclerview.widget.RecyclerView[@resource-id='com.hexin.plat.android:id/recyclerView']/android.widget.RelativeLayout[1]")
    # 关闭按钮
    close_btn = (AppiumBy.ID, "com.hexin.plat.android:id/close_btn")
    # 价格+1
    content_price_add = (AppiumBy.ID, "com.hexin.plat.android:id/content_price_add")
    # 价格-1
    content_price_sub = (AppiumBy.ID, "com.hexin.plat.android:id/content_price_sub")
    # 涨停
    zhangtingprice = (AppiumBy.ID, "com.hexin.plat.android:id/zhangtingprice")
    # 跌停
    dietingprice = (AppiumBy.ID, "com.hexin.plat.android:id/dietingprice")
    # 数量
    amount = (AppiumBy.ID, "com.hexin.plat.android:id/stockvolume")
    # 可买/可卖
    couldbuy = (AppiumBy.ID, "com.hexin.plat.android:id/couldbuy")
    # 全仓
    all_chicang = (AppiumBy.ID, "com.hexin.plat.android:id/all_chicang")
    # 半仓
    half_chicang = (AppiumBy.ID, "com.hexin.plat.android:id/half_chicang")
    # 1/3仓
    one_third_chicang = (AppiumBy.ID, "com.hexin.plat.android:id/one_third_chicang")
    # 1/4仓
    one_four_chicang = (AppiumBy.ID, "com.hexin.plat.android:id/one_four_chicang")
    # 买入/卖出按钮
    buy_mncg_button_container = (AppiumBy.ID, "com.hexin.plat.android:id/button_container")
    # 确认按钮
    ok_button = (AppiumBy.ID, "com.hexin.plat.android:id/ok_btn")

    # 持仓tab下元素
    # 仓位
    total_cangwei_text = (AppiumBy.ID, "com.hexin.plat.android:id/total_cangwei_text")
    # 分时开关
    swFenShiChart = (AppiumBy.ID, "com.hexin.plat.android:id/swFenShiChart")
    # 无持仓股过滤
    filter_label_stock_num_view = (AppiumBy.ID, "com.hexin.plat.android:id/filter_label_stock_num_view")
    # 没有持仓数据
    wt_chicang_empty_view = (AppiumBy.ID, "com.hexin.plat.android:id/wt_chicang_empty_view")  # 实盘
    empty_tip = (AppiumBy.ID, "com.hexin.plat.android:id/empty_tip")  # 模拟

    def click_buy_tab(self):
        """
        买入tab
        :return:
        """
        self.find_element(self.buy_btn).click()

    def click_sale_tab(self):
        """
        卖出tab
        :return:
        """
        self.find_element(self.sale_btn).click()

    def click_withdrawal_tab(self):
        """
        撤单tab
        :return:
        """
        self.find_element(self.withdrawal_btn).click()

    def click_holdings_tab(self):
        """
        持仓tab
        :return:
        """
        self.find_element(self.holdings_btn).click()

    def click_search_tab(self):
        """
        查询tab
        :return:
        """
        self.find_element(self.search_btn).click()

    def standby_loop(self):
        """
        待命循环
        appium 1分钟没操作会话会终止导致报错
        :return:
        """
        if self.find_element_by_wait(self.buy_mncg_button_container, timeout=1):
            self.click_element(self.holdings_btn)
            return True
        elif self.find_element_by_wait(self.total_cangwei_text, timeout=1):
            self.click_element(self.buy_btn)
            return True
        else:
            logger.error("不知道跳哪里了,重置一下")
            # 先按物理返回键
            self.driver.press_keycode(4)
            # self.click_element(self.tab_transaction)
            self.click_transaction_tab()
            self.click_element(self.tab_mn)
            # self.click_element(self.back_btn)
            self.click_holdings_menu()
            return False

    def enter_simulated_buy(self):
        """
        首次启动设备后首先进入的准备页面
        进入模拟买入页面
        :return:
        """
        # 广告页跳过
        # self.check_skip_btn()
        time.sleep(8)
        logger.info("到了首页")
        # 弹窗关闭
        self.check_close_btn()
        # 点击交易进入交易页面
        self.click_transaction_tab()
        # 关闭A股账户
        self.check_a_zh()
        # 点击模拟tab
        self.click_mn_tab()
        # 点击买入
        self.click_buy_menu()

    def query_elements(self):
        all_elements = self.find_elements(self.all_elm)
        logger.info(f"Number of elements found: {len(all_elements)}")
        for element1 in all_elements:
            if element1.is_displayed():
                element_id = element1.get_attribute("resource-id")
                element_text = element1.get_attribute("text")
                element_content_desc = element1.get_attribute("content-desc")
                logger.info(
                    f"element_id: {element_id}, element_text: {element_text}, element_content_desc: {element_content_desc}")

    def query_position(self, real=False):
        """
        新查询持仓
        兼容 实盘 和 模拟 页面，之后看如果报错过多需要做分离成两个函数
        :return:
        """
        self.click_holdings_tab()
        self.click_element(self.refresh_btn)
        time.sleep(2)
        self.click_element(self.refresh_btn)
        time.sleep(2)
        info = {}
        info['position'] = {}
        base_info_done = False
        parser = etree.XMLParser(encoding="UTF-8")
        base_ret = []
        swipe_time = 0

        def is_chinese(string):
            chart = string[0]
            if chart < u'\u4e00' or chart > u'\u9fff':
                return False
            return True

        def merge_lists(list1, list2):
            common_part = []
            for i in range(len(list1)):
                if list1[i:] == list2[:len(list1) - i]:
                    common_part = list1[i:]
                    break
            return list1 + list2[len(common_part):]

        # 循环获取页面源码
        while True:
            source = self.driver.page_source
            # if real:
            #     with open(f"real_data{swipe_time}_{int(time.time())}.xml", "w", encoding='utf8') as f:
            #         f.writelines(source)
            root = etree.XML(bytes(source, encoding='utf8'), parser=parser)
            if not base_info_done:
                try:
                    info['total_cangwei'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/total_cangwei_text"]')[
                            0].attrib.get('text')
                except:
                    info['total_cangwei'] = "仓位 --"
                logger.info(info['total_cangwei'])
                info['totalasset'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totalasset_value"]')[
                        0].attrib.get('text')
                logger.info(info['totalasset'])
                info['totallosewin'] = \
                    root.xpath(
                        '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totallosewin_value"]')[
                        0].attrib.get(
                        'text')
                logger.info(info['totallosewin'])
                try:
                    info['dangri_yingkui'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/dangri_yingkui_value"]')[
                            0].attrib.get(
                            'text')
                    logger.info(info['dangri_yingkui'])
                    info['dangri_yingkuibi'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/dangri_yingkuibi_value"]')[
                            0].attrib.get(
                            'text')
                    logger.info(info['dangri_yingkuibi'])
                except:
                    info['dangri_yingkui'] = "-"
                    info['dangri_yingkuibi'] = "-"
                info['totalworth'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totalworth_value"]')[
                        0].attrib.get('text')
                logger.info(info['totalworth'])
                info['canuse'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/canuse_value"]')[
                        0].attrib.get('text')
                logger.info(info['canuse'])
                info['canget'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/canget_value"]')[
                        0].attrib.get('text')
                logger.info(info['canget'])
                if info['canget'] and info['canuse'] and info['totalworth'] and info['dangri_yingkuibi'] and info[
                    'dangri_yingkui'] and info['totallosewin'] and info['totalasset'] and info['total_cangwei']:
                    base_info_done = True
                    logger.info(info)
            if real:
                len_ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]/android.widget.LinearLayout')
                logger.info(len(len_ret))
                ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]//android.widget.TextView[contains(@class,"android.widget.TextView")]')
                logger.info(len(ret))
            else:
                len_ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]/android.widget.RelativeLayout')
                logger.info(len(len_ret))
                ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]//android.widget.TextView[contains(@class,"android.widget.TextView")]')
                logger.info(len(ret))
            if "com.hexin.plat.android:id/wt_chicang_empty_view" in source or "com.hexin.plat.android:id/empty_tip" in source:
                logger.info("元素显示没有持仓!")
                pass
            elif len(ret) == 0 or len(len_ret) == 0:
                logger.info("没有持仓!")
                pass
            ret_text = []
            for i in ret:
                ret_text.append(i.attrib.get('text'))
            if not base_ret:
                base_ret.extend(ret_text)
            else:
                base_ret = merge_lists(base_ret, ret_text)
            logger.info(len(base_ret))
            logger.info(base_ret)
            if swipe_time < 2:
                self.swipe_up_half()
                swipe_time += 1
            else:
                for n in range(len(base_ret)):
                    if n % 8 == 0:
                        stockname = base_ret[n]
                        if stockname in list(info['position'].keys()) or not is_chinese(stockname) or n + 7 > len(
                                base_ret):
                            continue
                        shizhi = base_ret[1 + n]
                        yk = base_ret[2 + n]
                        ykb = base_ret[3 + n]
                        chicang = base_ret[4 + n]
                        keyong = base_ret[5 + n]
                        chengben = base_ret[6 + n]
                        xianjia = base_ret[7 + n]
                        info['position'][stockname] = {"shizhi": shizhi, "yk": yk, "ykb": ykb, "chicang": chicang,
                                                       "keyong": keyong, "chengben": chengben, "xianjia": xianjia}
                        logger.info(info['position'][stockname])
                break
        logger.info(info)
        self.click_element(self.back_btn)
        self.click_holdings_menu()
        return info

    def query_position1(self, real=False):
        """
        新查询持仓
        兼容 实盘 和 模拟 页面，之后看如果报错过多需要做分离成两个函数
        :return:
        """
        self.click_holdings_tab()
        self.click_element(self.refresh_btn)
        time.sleep(2)
        info = {}
        info['position'] = {}
        base_info_done = False
        parser = etree.XMLParser(encoding="UTF-8")
        yy_position_num = 0
        swipe_time = 0

        def is_chinese(string):
            chart = string[0]
            if chart < u'\u4e00' or chart > u'\u9fff':
                return False
            return True

        # 循环获取页面源码
        while True:
            source = self.driver.page_source
            # if real:
            #     with open(f"real_data{swipe_time}_{int(time.time())}.xml", "w", encoding='utf8') as f:
            #         f.writelines(source)
            root = etree.XML(bytes(source, encoding='utf8'), parser=parser)
            if not base_info_done:
                try:
                    info['total_cangwei'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/total_cangwei_text"]')[
                            0].attrib.get('text')
                except:
                    info['total_cangwei'] = "仓位 --"
                logger.info(info['total_cangwei'])
                info['totalasset'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totalasset_value"]')[
                        0].attrib.get('text')
                logger.info(info['totalasset'])
                info['totallosewin'] = \
                    root.xpath(
                        '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totallosewin_value"]')[
                        0].attrib.get(
                        'text')
                logger.info(info['totallosewin'])
                try:
                    info['dangri_yingkui'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/dangri_yingkui_value"]')[
                            0].attrib.get(
                            'text')
                    logger.info(info['dangri_yingkui'])
                    info['dangri_yingkuibi'] = \
                        root.xpath(
                            '//android.widget.TextView[@resource-id="com.hexin.plat.android:id/dangri_yingkuibi_value"]')[
                            0].attrib.get(
                            'text')
                    logger.info(info['dangri_yingkuibi'])
                except:
                    info['dangri_yingkui'] = "-"
                    info['dangri_yingkuibi'] = "-"
                info['totalworth'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/totalworth_value"]')[
                        0].attrib.get('text')
                logger.info(info['totalworth'])
                info['canuse'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/canuse_value"]')[
                        0].attrib.get('text')
                logger.info(info['canuse'])
                info['canget'] = \
                    root.xpath('//android.widget.TextView[@resource-id="com.hexin.plat.android:id/canget_value"]')[
                        0].attrib.get('text')
                logger.info(info['canget'])
                if info['canget'] and info['canuse'] and info['totalworth'] and info['dangri_yingkuibi'] and info[
                    'dangri_yingkui'] and info['totallosewin'] and info['totalasset'] and info['total_cangwei']:
                    base_info_done = True
                    logger.info(info)
            if real:
                len_ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]/android.widget.LinearLayout')
                logger.info(len(len_ret))
                ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]//android.widget.TextView[contains(@class,"android.widget.TextView")]')
                logger.info(len(ret))
            else:
                len_ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]/android.widget.RelativeLayout')
                logger.info(len(len_ret))
                ret = root.xpath(
                    '//*[@class="androidx.recyclerview.widget.RecyclerView"]//android.widget.TextView[contains(@class,"android.widget.TextView")]')
                logger.info(len(ret))
            if "com.hexin.plat.android:id/wt_chicang_empty_view" in source or "com.hexin.plat.android:id/empty_tip" in source:
                logger.info("元素显示没有持仓!")
                pass
            elif len(ret) == 0 or len(len_ret) == 0:
                logger.info("没有持仓!")
                pass
            elif len(ret) / len(len_ret) == 8:
                for n in range(len(ret)):
                    if n % 8 == 0:
                        stockname = ret[n].attrib.get('text')
                        if stockname in list(info['position'].keys()) or not is_chinese(stockname):
                            continue
                        shizhi = ret[1 + n].attrib.get('text')
                        yk = ret[2 + n].attrib.get('text')
                        ykb = ret[3 + n].attrib.get('text')
                        chicang = ret[4 + n].attrib.get('text')
                        keyong = ret[5 + n].attrib.get('text')
                        chengben = ret[6 + n].attrib.get('text')
                        xianjia = ret[7 + n].attrib.get('text')
                        info['position'][stockname] = {"shizhi": shizhi, "yk": yk, "ykb": ykb, "chicang": chicang,
                                                       "keyong": keyong, "chengben": chengben, "xianjia": xianjia}
                        logger.info(info['position'][stockname])
            else:
                logger.info("数据获取不完整")
                if len(ret) % 8 == 0:
                    pass
                elif (len(ret) - 4) % 8 != 0:
                    # 保存当时的页面源码，留之后分析
                    with open(f"data{swipe_time}_{int(time.time())}.xml", "w", encoding='utf8') as f:
                        f.writelines(source)
                    self.swipe_up_half()
                    self.swipe_down_half()
                    swipe_time = 0
                    continue
                elif is_chinese(ret[0].attrib.get('text')):
                    logger.info("后面减四个")
                    ret = ret[:-4]
                else:
                    logger.info("前面减四个")
                    ret = ret[4:]
                for n in range(len(ret)):
                    if n % 8 == 0:
                        stockname = ret[n].attrib.get('text')
                        if stockname in list(info['position'].keys()) or not is_chinese(stockname):
                            continue
                        shizhi = ret[1 + n].attrib.get('text')
                        yk = ret[2 + n].attrib.get('text')
                        ykb = ret[3 + n].attrib.get('text')
                        chicang = ret[4 + n].attrib.get('text')
                        keyong = ret[5 + n].attrib.get('text')
                        chengben = ret[6 + n].attrib.get('text')
                        xianjia = ret[7 + n].attrib.get('text')
                        info['position'][stockname] = {"shizhi": shizhi, "yk": yk, "ykb": ykb, "chicang": chicang,
                                                       "keyong": keyong, "chengben": chengben, "xianjia": xianjia}
                        logger.info(info['position'][stockname])
            position_num = len(info['position'])
            logger.info(f"chicang shu:{position_num}")
            if position_num == yy_position_num and swipe_time != 0:
                break
            else:
                self.swipe_up_half()
                yy_position_num = position_num
                swipe_time += 1
        logger.info(info)
        self.click_element(self.back_btn)
        self.click_holdings_menu()
        return info

    def buy(self, stockcode: str, price: str = None, amount: str = None, bidding=False):
        """
        买入
        :param stockcode: 股票代码
        :param price: 买入价格
        :param amount: 买入数量
        :param bidding: 是否竞价
        :return:
        """
        self.click_buy_tab()
        self.click_element(self.auto_stockcode)
        text = self.find_element_by_wait(self.content_stock).text
        logger.info(text)
        logger.info(f'买入{stockcode}')
        if text and text != "股票代码/简拼":
            self.click_element(self.clear_button, timeout=1)
        self.input_number(stockcode)
        self.click_element(self.recyclerView, timeout=1)
        if bidding:
            self.find_element_by_wait(self.zhangtingprice).click()
        else:
            # todo 买入价格以后需要改成输入框
            if price:
                add = self.find_element_by_wait(self.content_price_add)
                add.click()
                add.click()
                add.click()
                add.click()
                add.click()
            else:
                add = self.find_element_by_wait(self.content_price_add)
                add.click()
                add.click()
                add.click()
                add.click()
                add.click()
        logger.info("输入了买入金额")
        if amount:
            self.find_element(self.amount).click()
            self.input_number(amount)
        else:
            self.find_element_by_wait(self.all_chicang).click()
        logger.info("输入了买入数量:{}".format(amount))
        self.click_element(self.buy_mncg_button_container, timeout=2)
        self.click_element(self.ok_button, timeout=2)
        self.click_element(self.ok_button, timeout=2)

    def sale(self, stockcode: str, price: str = None, amount: str = None, bidding=False):
        """
        卖出
        :param stockcode: 股票代码
        :param price: 卖出价格
        :param amount: 卖出数量
        :param bidding: 是否竞价
        :return:
        """
        self.click_sale_tab()
        self.click_element(self.auto_stockcode)
        text = self.find_element_by_wait(self.content_stock).text
        logger.info(text)
        if text and text != "股票代码/简拼":
            self.click_element(self.clear_button, timeout=1)
        self.input_number(stockcode)
        self.click_element(self.recyclerView, timeout=1)
        if bidding:
            self.find_element_by_wait(self.dietingprice).click()
        else:
            # todo 卖出价格以后需要改成输入框
            if price:
                sub = self.find_element_by_wait(self.content_price_sub)
                sub.click()
                sub.click()
                sub.click()
                sub.click()
                sub.click()
            else:
                sub = self.find_element_by_wait(self.content_price_sub)
                sub.click()
                sub.click()
                sub.click()
                sub.click()
                sub.click()
        logger.info("输入了卖出金额")
        if amount:
            self.find_element(self.amount).click()
            self.input_number(amount)
        else:
            self.find_element_by_wait(self.all_chicang).click()
        logger.info("输入了卖出数量:{}".format(amount))
        self.click_element(self.buy_mncg_button_container, timeout=2)
        self.click_element(self.ok_button, timeout=2)
        self.click_element(self.ok_button, timeout=2)
